package com.service;

import java.sql.Timestamp;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.dao.IAmsRetToolHbtDao;
import com.icim.service.ICIMBaseService;
import com.model.Ams_ret_tool_hbt;
import com.model.Ret_tool_st;
import com.rtnBean.NotFoundRtnBeen;
import com.tx.Amshbt.AmshbtI;
import com.tx.Amshbt.AmshbtIA;
import com.tx.Amshbt.AmshbtO;
import com.util.MqOpe;
import com.util.Util;

import static com.def.GenericDef.*;

import org.springframework.context.annotation.Scope;

@Scope("prototype")
@Service("AmshbtService")
public class AmshbtService extends ICIMBaseService{
	private static Logger logger = Logger.getLogger(AmshbtService.class);
	private static String TX_NAME = T_AMSHBT;

	private AmshbtI inTrx;
	private AmshbtO outTrx;
	private MqOpe mqOpe;

	private String gszMsgBuf = "";
	private Timestamp gEvtTimestamp;

	@Autowired
	private IAmsRetToolHbtDao amsRetToolHbtDao;

	public String subMainProc(String strInMsg) {
		long rtnCode = _NORMAL;
		String outMsg = null;
		gszMsgBuf = "";
		gEvtTimestamp = Util.getCurrentTimestamp();
		inTrx = new AmshbtI();
		outTrx = new AmshbtO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setType_id(TRX_OUT);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		mqOpe = new MqOpe();

		try {
			inTrx = (AmshbtI) mqOpe.inStr2Obj(strInMsg, inTrx);
			logger.info("InTrx is " + strInMsg);

			rtnCode = subMainProc2(inTrx.getAction_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				amsRetToolHbtDao.flushCurSession();
			}
		} catch (Exception ex) {
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logger.error(Util.stackTraceToString(ex));
		} finally {
			outMsg = mqOpe.obj2Str(outTrx);
			return outMsg;
		}
	}

	private long subMainProc2(char actionType) {
		long lRc = _NORMAL;

		switch (actionType) {
			case 'A': {
				lRc = reportHeartBeat();
				break;
			}
			case 'M': {
				lRc = modifyHeartBeat();
				break;
			}
			case 'D': {
				lRc = deleteHeartBeat();
				break;
			}
			default: {
				gszMsgBuf = "Invalide type input: [" + actionType + "]";
				return E_AMSHBT_INVALID_INPUT;
			}
		}

		return lRc;
	}

	/**
	 * Check input msg's toolID item
	 * 
	 * @return
	 */
	private long inputToolCheck() {
		long lRc = _NORMAL;
		if (Util.isSpaceCheck(inTrx.getTool_id())) {
			gszMsgBuf = "Tool id is null!";
			return E_AMSHBT_TOOL_ID_IS_NULL;
		}

		return _NORMAL;
	}

	/**
	 * Delete heartBeat set
	 * 
	 * @return
	 */
	private long deleteHeartBeat() {
		long lRc = _NORMAL;
		if (null == inTrx.getIary_cnt()) {
			gszMsgBuf = "Delete count invalied[" + inTrx.getIary_cnt() + "]!";
			return E_AMSHBT_IARY_CNT_NULL;
		} else {
			if (inTrx.getIary_cnt() < 0) {
				gszMsgBuf = "Delete count invalied[" + inTrx.getIary_cnt()
						+ "]!";
				return E_AMSHBT_IARY_CNT_INVALIED;
			}
			if (inTrx.getIary_cnt() != inTrx.getIary().size()) {
				gszMsgBuf = "Delete count [" + inTrx.getIary_cnt()
						+ "] unmatch with tool list's count ["
						+ inTrx.getIary().size() + "]!";
				return E_AMSHBT_IARY_CNT_UNMATCH;
			}
		}

		if (Util.isSpaceCheck(inTrx.getEvt_user())) {
			gszMsgBuf = "Evt user is null!";
			return E_AMSHBT_EVT_USER_IS_NULL;
		}

		for (AmshbtIA amhbtIA : inTrx.getIary()) {
			Ams_ret_tool_hbt ams_ret_tool_hbt = new Ams_ret_tool_hbt();
			ams_ret_tool_hbt = amsRetToolHbtDao.get(amhbtIA.getTool_id());
			if (null == ams_ret_tool_hbt) {
				gszMsgBuf = new NotFoundRtnBeen(amhbtIA.getTool_id(),
						Ams_ret_tool_hbt.class).toString();
				return E_AMS_RET_TOOL_HBT + E_DELETE_NOT_FOUND;
			}

			amsRetToolHbtDao.delete(ams_ret_tool_hbt);
			logger.info("[" + amhbtIA.getTool_id() + "] delete by ["
					+ inTrx.getEvt_user() + "]");
		}

		return _NORMAL;
	}

	/**
	 * User set HBT attribute
	 * 
	 * @return
	 */
	private long modifyHeartBeat() {
		long lRc = _NORMAL;

		lRc = inputToolCheck();
		if (_NORMAL != lRc) {
			return lRc;
		}

		if (Util.isSpaceCheck(inTrx.getEvt_user())) {
			gszMsgBuf = "Evt user is null!";
			return E_AMSHBT_EVT_USER_IS_NULL;
		}
		if (null == inTrx.getPln_alm_cnt()) {
			gszMsgBuf = "Plan alarm count invalied[" + inTrx.getPln_alm_cnt()
					+ "]!";
			return E_AMSHBT_PLN_ALM_CNT_NULL;
		} else {
			if (inTrx.getPln_alm_cnt() < 0) {
				gszMsgBuf = "Plan alarm count invalied["
						+ inTrx.getPln_alm_cnt() + "]!";
				return E_AMSHBT_PLN_ALM_CNT_INVALIED;
			}
		}

		String toolId = inTrx.getTool_id();

		Ams_ret_tool_hbt ams_ret_tool_hbt = new Ams_ret_tool_hbt();
		ams_ret_tool_hbt = amsRetToolHbtDao.get(toolId);
		if (null == ams_ret_tool_hbt) {
			gszMsgBuf = new NotFoundRtnBeen(toolId, Ams_ret_tool_hbt.class)
					.toString();
			return E_AMS_RET_TOOL_HBT + E_READ_NOT_FOUND;
		}

		ams_ret_tool_hbt.setPln_alm_cnt(inTrx.getPln_alm_cnt());
		ams_ret_tool_hbt.setEvt_user(inTrx.getEvt_user());
		ams_ret_tool_hbt.setEvt_timestamp(gEvtTimestamp);
		amsRetToolHbtDao.update(ams_ret_tool_hbt);

		return _NORMAL;
	}

	/**
	 * Client report new heartbeat
	 * 
	 * @return
	 */
	private long reportHeartBeat() {
		long lRc = _NORMAL;

		lRc = inputToolCheck();
		if (_NORMAL != lRc) {
			return lRc;
		}

		String toolId = inTrx.getTool_id();

		Ams_ret_tool_hbt ams_ret_tool_hbt = new Ams_ret_tool_hbt();
		ams_ret_tool_hbt = amsRetToolHbtDao.get(toolId);
		if (null == ams_ret_tool_hbt) {
			Ams_ret_tool_hbt ams_ret_tool_hbt_new = new Ams_ret_tool_hbt();
			ams_ret_tool_hbt_new.setTool_id_fk(toolId);
			ams_ret_tool_hbt_new.setHbt_bg_timestamp(gEvtTimestamp);
			ams_ret_tool_hbt_new.setHbt_cr_timestamp(gEvtTimestamp);
			ams_ret_tool_hbt_new.setPln_alm_cnt(0);
			ams_ret_tool_hbt_new.setAc_alm_cnt(0);
			ams_ret_tool_hbt_new.setEvt_user(toolId);
			ams_ret_tool_hbt_new.setEvt_timestamp(gEvtTimestamp);

			amsRetToolHbtDao.save(ams_ret_tool_hbt_new);
		} else {
			ams_ret_tool_hbt.setHbt_pv_timestamp(ams_ret_tool_hbt
					.getHbt_cr_timestamp());
			ams_ret_tool_hbt.setHbt_cr_timestamp(gEvtTimestamp);
			ams_ret_tool_hbt.setEvt_user(toolId);
			ams_ret_tool_hbt.setEvt_timestamp(gEvtTimestamp);

			amsRetToolHbtDao.update(ams_ret_tool_hbt);
		}

		return _NORMAL;
	}

}
